<template>
  <view class="login-container">
    <!-- 顶部自定义导航栏 -->
    <view class="custom-nav">
      <text class="nav-title">易腾工单-登录</text>
    </view>

    <!-- 系统标题区 -->
    <view class="system-header">
      <view class="system-title">易腾工单系统</view>
      <view class="system-subtitle">高效管理 · 便捷工单</view>
    </view>

    <!-- 登录卡片 -->
    <view class="login-card">
      <!-- 用户名输入组 -->
      <view class="form-group">
        <view class="input-group">
          <icon type="user" size="24" class="input-icon" />
          <input 
            type="text" 
            v-model="username" 
            placeholder="请输入用户名/手机号" 
            class="form-input" 
            @focus="clearError('username')"
          />
        </view>
        <view v-if="usernameError" class="error-tip">{{ usernameError }}</view>
      </view>

      <!-- 密码输入组 -->
      <view class="form-group">
        <view class="input-group">
          <icon type="locked" size="24" class="input-icon" />
          <input
            v-if="!showPassword"
            type="password"
            v-model="password"
            placeholder="请输入密码"
            class="form-input"
            @focus="clearError('password')"
          />
          <input
            v-if="showPassword"
            type="text"
            v-model="password"
            placeholder="请输入密码"
            class="form-input"
            @focus="clearError('password')"
          />
          <text 
            class="toggle-password" 
            @click="toggleShowPassword"
          >{{ showPassword ? '🔓' : '🔒' }}</text>
        </view>
        <view v-if="passwordError" class="error-tip">{{ passwordError }}</view>
        
        <!-- 记住密码选项 -->
        <view class="remember-me-container">
          <checkbox 
            :checked="rememberMe"
            @change="handleRememberChange"
            class="remember-me-checkbox"
            color="#5555ff"
          >
            记住密码
          </checkbox>
          <text class="security-tip">
            ⚠️ 提示：密码将存储在本地，非个人设备请勿勾选
          </text>
        </view>
      </view>

      <!-- 验证码输入组 -->
      <view class="form-group captcha-group">
        <view class="input-group captcha-input-group">
          <icon type="code" size="24" class="input-icon" />
          <input 
            type="text" 
            v-model="captcha" 
            placeholder="请输入验证码（不区分大小写）" 
            class="form-input captcha-input" 
            maxlength="4"
            @focus="clearError('captcha')"
          />
        </view>
        <view class="captcha-area">
          <canvas canvas-id="captchaCanvas" class="captcha-img" @click="refreshCaptcha"></canvas>
          <view class="refresh-icon" @click="refreshCaptcha">
            <icon type="refresh" size="22" />
          </view>
        </view>
      </view>
      <view v-if="captchaError" class="error-tip captcha-error-tip">{{ captchaError }}</view>

      <!-- 接口错误提示 -->
      <view v-if="loginApiError" class="error-tip api-error-tip">{{ loginApiError }}</view>

      <!-- 登录按钮 -->
      <button class="login-btn" @click="handleLogin" :disabled="isLoading">
        <view v-if="isLoading" class="loading-indicator">
          <view class="loading-dot" v-for="i in 3" :key="i"></view>
        </view>
        <view v-else>登录</view>
      </button>
    </view>
  </view> 
</template>
<script>
import request from '@/api/request.js';

export default {
  data() {
    return {
      username: '',
      password: '',
      captcha: '',
      captchaCode: '', // 存储生成的验证码（小写）
      isLoading: false,
      usernameError: '',
      passwordError: '',
      captchaError: '',
      loginApiError: '',
      showPassword: false,
      rememberMe: false,
    }
  },
  onLoad() {
    this.loadSavedCredentials();
  },
  onReady() {
    this.generateCaptcha(); // 页面渲染后生成简化验证码
  },
  methods: {
    loadSavedCredentials() {
      const savedUsername = uni.getStorageSync('savedUsername');
      const savedPassword = uni.getStorageSync('savedPassword');
      
      if (savedUsername && savedPassword) {
        this.username = savedUsername;
        this.password = savedPassword;
        this.rememberMe = true;
      }
    },
    
    handleRememberChange(e) {
      this.rememberMe = e.detail.value;
    },
    
    // 1. 简化验证码：字符集仅保留「数字+小写字母」，减少干扰元素
    generateCaptcha() {
      this.captcha = '';
      // 简化字符集：只包含数字和小写字母（去掉大写，降低复杂度）
      const chars = '0123456789abcdefghijklmnopqrstuvwxyz';
      let code = '';
      for (let i = 0; i < 4; i++) {
        code += chars.charAt(Math.floor(Math.random() * chars.length));
      }
      this.captchaCode = code; // 直接存储小写验证码，无需额外转换

      const ctx = uni.createCanvasContext('captchaCanvas', this);
      // 简化背景：纯色背景（替代渐变，更简洁）
      ctx.setFillStyle('#f9f9f9');
      ctx.fillRect(0, 0, 120, 40);

      // 2. 减少干扰：干扰线从8条减为3条，干扰点从50个减为20个
      // 简化干扰线
      for (let i = 0; i < 3; i++) {
        ctx.setStrokeStyle(this.getRandomColor());
        ctx.setLineWidth(Math.random() * 1 + 0.3); // 线宽变细，减少干扰
        ctx.beginPath();
        ctx.moveTo(Math.random() * 120, Math.random() * 40);
        ctx.lineTo(Math.random() * 120, Math.random() * 40);
        ctx.stroke();
      }

      // 简化干扰点
      for (let i = 0; i < 20; i++) {
        ctx.setFillStyle(this.getRandomColor());
        ctx.beginPath();
        ctx.arc(Math.random() * 120, Math.random() * 40, Math.random() * 1 + 0.3, 0, 2 * Math.PI); // 点变小
        ctx.fill();
      }

      // 3. 简化文字：旋转角度减小（更易读），字体更大
      for (let i = 0; i < 4; i++) {
        ctx.setFillStyle(this.getRandomColor());
        // 旋转角度从0.6减为0.3（文字更正，减少识别难度）
        const angle = (Math.random() - 0.5) * 0.3;
        // 字体大小从20-26调整为22-26（更大更清晰）
        const fontSize = 22 + Math.random() * 4;
        ctx.setFontSize(fontSize);
        
        ctx.save();
        ctx.translate(22 + i * 24, 26);
        ctx.rotate(angle);
        ctx.fillText(this.captchaCode.charAt(i), 0, 0);
        ctx.restore();
      }
      
      ctx.draw();
    },

    // 随机颜色保留（但颜色亮度提高，避免过暗）
    getRandomColor() {
      const r = 80 + Math.floor(Math.random() * 100); // 红色通道亮度提高
      const g = 80 + Math.floor(Math.random() * 100); // 绿色通道亮度提高
      const b = 80 + Math.floor(Math.random() * 100); // 蓝色通道亮度提高
      return `rgb(${r}, ${g}, ${b})`;
    },

    refreshCaptcha() {
      this.generateCaptcha();
    },

    clearError(type) {
      if (type === 'username') this.usernameError = '';
      if (type === 'password') this.passwordError = '';
      if (type === 'captcha') this.captchaError = '';
      this.loginApiError = '';
    },

    toggleShowPassword() {
      this.showPassword = !this.showPassword;
    },

    // 4. 不区分大小写校验：用户输入转小写后与存储的小写验证码对比
    handleLogin() {
      this.usernameError = '';
      this.passwordError = '';
      this.captchaError = '';
      this.loginApiError = '';

      let isFormValid = true;
      
      if (!this.username.trim()) {
        this.usernameError = '请输入用户名';
        isFormValid = false;
      }
      
      if (!this.password.trim()) {
        this.passwordError = '请输入密码';
        isFormValid = false;
      }
      
      // 验证码校验：先去空格+转小写，再对比（实现不区分大小写）
      const userInputCaptcha = this.captcha.trim().toLowerCase();
      if (!userInputCaptcha) {
        this.captchaError = '请输入验证码';
        isFormValid = false;
      } else if (userInputCaptcha !== this.captchaCode) { // 直接对比（captchaCode已为小写）
        this.captchaError = '验证码不正确，请重新输入';
        this.refreshCaptcha();
        isFormValid = false;
      }

      if (!isFormValid) return;

      this.isLoading = true;
      request.post('/api/loginInfo/login', {
        account: this.username,
        password: this.password
      })
      .then(res => {
        this.isLoading = false;
        const loginData = res;
        
        if (this.rememberMe) {
          uni.setStorageSync('savedUsername', this.username);
          uni.setStorageSync('savedPassword', this.password);
        } else {
          uni.removeStorageSync('savedUsername');
          uni.removeStorageSync('savedPassword');
        }

        const roleLogos = loginData.roleLogos || [];
        const roleLogo = loginData.roles?.[0]?.roleLogo || roleLogos[0];

        if (roleLogos.length === 0) {
          uni.showToast({ title: '未分配角色，请联系管理员', icon: 'none', duration: 3000 });
          return;
        }

        uni.setStorageSync('token', loginData.token);
        uni.setStorageSync('roleLogo', roleLogo);
        uni.setStorageSync('roleLogos', roleLogos);
        uni.setStorageSync('userInfo', loginData.user);
        uni.setStorageSync('permissions', loginData.permissions);

        const userId = loginData.user.id || loginData.user.userid || loginData.user.userId;
        if (userId) {
          uni.setStorageSync('userId', userId);
        }

        uni.showToast({ title: '登录成功', icon: 'success' });

        setTimeout(() => {
          if (roleLogos.includes('DISPATCHER')) {
            uni.reLaunch({ url: '/pages/Employee/index/index' });
          } else if (roleLogos.includes('CUSTOMER')) {
            uni.reLaunch({ url: '/pages/User/workorder/workorder' });
          } else {
            uni.showToast({ title: `当前角色【${roleLogos.join(',')}】无访问权限`, icon: 'none', duration: 3000 });
          }
        }, 1000);
      })
      .catch(err => {
        this.isLoading = false;
        if (err.type === 'network') {
          this.loginApiError = err.msg;
        } else if (err.type === 'business') {
          this.loginApiError = err.msg;
          this.refreshCaptcha();
        } else {
          this.loginApiError = '登录失败，请稍后重试';
          this.refreshCaptcha();
        }
      });
    }
  }
}
</script>
<style scoped>
/* 样式无核心修改，仅保留原样式 */
.login-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 40rpx;
  padding-top: 140rpx;
  box-sizing: border-box;
  background-color: #f5f7fa;
}

.custom-nav {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100rpx;
  background-color: #5555ff;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.nav-title {
  font-size: 36rpx;
  color: #fff;
  font-weight: bold;
}

.system-header {
  text-align: center;
  margin-bottom: 60rpx;
  color: #333;
}
.system-title {
  font-size: 48rpx;
  font-weight: bold;
  margin-bottom: 12rpx;
}
.system-subtitle {
  font-size: 28rpx;
  color: #666;
}

.login-card {
  width: 100%;
  max-width: 520rpx;
  background-color: #fff;
  padding: 60rpx 48rpx;
  border-radius: 20rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
}

.form-group {
  margin-bottom: 30rpx;
  position: relative;
}
.input-group {
  display: flex;
  align-items: center;
  height: 96rpx;
  border: 2rpx solid #eaeaea;
  border-radius: 12rpx;
  padding: 0 24rpx;
  transition: border-color 0.3s;
}
.input-group:focus-within {
  border-color: #5555ff;
}
.input-icon {
  color: #888;
  margin-right: 20rpx;
  font-size: 28rpx;
}
.toggle-password {
  cursor: pointer;
  margin-left: auto;
  color: #888;
}
.toggle-password:hover {
  color: #5555ff;
}
.form-input {
  flex: 1;
  height: 100%;
  font-size: 32rpx;
  color: #333;
  outline: none;
  border: none;
  background: transparent;
}

.remember-me-container {
  margin-top: 20rpx;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.remember-me-checkbox {
  font-size: 28rpx;
  color: #666;
  display: flex;
  align-items: center;
}
.remember-me-checkbox .uni-checkbox-input {
  margin-right: 10rpx;
}
.security-tip {
  font-size: 24rpx;
  color: #ff6b6b;
  margin-top: 8rpx;
  line-height: 1.4;
}

.captcha-group {
  display: flex;
  align-items: center;
  gap: 24rpx;
}
.captcha-input-group {
  flex: 1;
}
.captcha-area {
  display: flex;
  align-items: center;
  position: relative;
}
.captcha-img {
  width: 240rpx;
  height: 96rpx;
  border-radius: 12rpx;
  background-color: #f3f3f3;
  cursor: pointer;
}
.refresh-icon {
  position: absolute;
  right: 12rpx;
  top: 50%;
  transform: translateY(-50%);
  background-color: rgba(255, 255, 255, 0.8);
  padding: 8rpx;
  border-radius: 50%;
  color: #888;
  cursor: pointer;
}

.error-tip {
  margin-top: 12rpx;
  font-size: 24rpx;
  color: #ff3b30;
  line-height: 32rpx;
  animation: shake 0.3s ease;
}
.api-error-tip {
  text-align: center;
  margin-bottom: 20rpx;
}

.login-btn {
  width: 100%;
  height: 96rpx;
  line-height: 96rpx;
  background-color: #5555ff;
  color: #fff;
  font-size: 34rpx;
  border-radius: 12rpx;
  margin-top: 20rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-btn::after {
  border: none;
}
.login-btn:disabled {
  background-color: #b8b8b8;
  opacity: 0.8;
}

.loading-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40rpx;
}
.loading-dot {
  width: 12rpx;
  height: 12rpx;
  border-radius: 50%;
  background-color: #fff;
  margin: 0 4rpx;
  animation: pulse 1.2s infinite ease-in-out;
}
.loading-dot:nth-child(2) {
  animation-delay: 0.4s;
}
.loading-dot:nth-child(3) {
  animation-delay: 0.8s;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4rpx); }
  75% { transform: translateX(4rpx); }
}
@keyframes pulse {
  0%, 100% { transform: scale(0.8); opacity: 0.5; }
  50% { transform: scale(1.2); opacity: 1; }
}
</style>